import time

from selenium.common import TimeoutException
from selenium.webdriver.common.by import By

from openGaussMigrate.common.base import Base
from openGaussMigrate.common.com_bro_action import ComBroAction
from openGaussMigrate.common.com_log import ComLog


class ComUnitAction(ComBroAction):
    def __init__(self, driver_p, url_p):
        """
        初始化
        :param driver_p: 浏览器驱动存放路径
        :param url_p: url路径
        """
        super(ComUnitAction, self).__init__(driver_p, url_p)
        self.log = ComLog(self.__class__.__name__)

    def __enter__(self):
        """
        入口函数，打开浏览器并访问url
        :return: 类实例
        """
        self.open()
        return self

    def __exit__(self, exc_type, exc_val, exc_tb):
        """
        出口函数
        :param exc_type: 异常类型
        :param exc_val: 异常值
        :param exc_tb: 异常堆栈信息
        """
        self.close()
        if exc_type:
            self.log.info(f'exc_type: {exc_type}')
            self.log.info(f'exc_val: {exc_val}')

    def login(self, user, pwd):
        """
        登录
        :param user:用户名
        :param pwd: 密码
        """
        try:
            self.wait_ele(By.XPATH, '//*[text()="您的连接不是私密连接"]')
        except TimeoutError:
            self.log.info('无告警，可正常进入！')
        else:
            self.wait_click('//button[contains(text(),"高级")]')
            self.wait_click('//a[contains(text(),"继续前往")]')
        finally:
            self.wait_input('//input[@placeholder="账号"]', user)
            self.wait_input('//input[@placeholder="密码"]', pwd)
            self.wait_click('//*[text()="记住密码"]')
            self.click('//button[text()="登录"]')
            time.sleep(1)

    def logout(self):
        """
        登出
        """
        pull_img = '//span[text()="admin"]/following-sibling::img'
        self.wait_click(pull_img)
        exit_btn = '//span[text()="退出登录"]'
        self.wait_click(exit_btn)

    def install_plugin(self, plugin_name_cn, plugin_path):
        self.log.info('步骤①：打开插件管理页面')
        btn_xpath = '//*[text()="插件管理" and contains(@class, "arco-menu")]'
        self.wait_click(btn_xpath)

        self.log.info('步骤②：点击右上角“安装插件”按钮')
        btn_xpath = '//*[text()="安装插件" and contains(@class, "arco-btn")]'
        self.wait_click(btn_xpath)

        self.log.info('步骤③：将插件Jar包拖入安装窗口')
        upload_xpath = '//*[text()="点击上传"]'
        self.wait_click(upload_xpath)
        time.sleep(2)
        Base.upload(plugin_path)
        start_xpath = '//*[@class="arco-upload-icon arco-upload-icon-start"]'
        self.wait_click(start_xpath)
        time.sleep(3)

        self.log.info('步骤④：确认安装【结果1】【结果2】，【结果1】提示安装成功，【结果2】插件菜单出现，可打开插件Tab')
        hint_xpath = '//*[text()="Install success"]'
        self.wait_ele(By.XPATH, hint_xpath)

        self.refresh()

        menu_xpath = f'//*[@class="arco-menu-title" and text()=' \
            f'"{plugin_name_cn}"]'
        self.wait_click(menu_xpath)

        self.log.info('步骤⑤：关闭打开的tag')
        close_xpath = '//*[@class="tag-link" and text()="插件管理"]/' \
                      'following-sibling::span'
        self.wait_click(close_xpath)

    def uninstall_plugin(self, plugin_name):
        self.log.info('步骤①：打开插件管理页面')
        btn_xpath = '//*[text()="插件管理" and contains(@class, "arco-menu")]'
        self.wait_click(btn_xpath)

        self.log.info('步骤②：点击卸载按钮，确认')
        plugin_xpath = f'//*[@class="plugin-name-con"]/div[text()=' \
            f'"{plugin_name}"]'
        del_xpath = f'{plugin_xpath}/ancestor::div[@class="list-item"]/' \
            f'descendant::button[text()="卸载"]'
        self.wait_click(del_xpath)
        confirm_btn_xpath = '//*[@class="arco-popconfirm-footer"]/' \
                            'descendant::button[text()="确定"]'
        self.wait_click(confirm_btn_xpath)
        time.sleep(2)

        self.log.info('步骤③：关闭打开的tag')
        close_xpath = '//*[@class="tag-link" and text()="插件管理"]/' \
                      'following-sibling::span'
        self.wait_click(close_xpath)

    def is_plugin_intalled(self, plugin_name):
        self.log.info('步骤①：打开插件管理页面')
        btn_xpath = '//*[text()="插件管理" and contains(@class, "arco-menu")]'
        self.wait_click(btn_xpath)

        self.log.info('步骤②：查看插件是否已安装')
        plugin_xpath = f'//*[@class="plugin-name-con"]/div[text()=' \
            f'"{plugin_name}"]'
        try:
            self.wait_ele(By.XPATH, plugin_xpath)
        except TimeoutException:
            return False
        else:
            return True

    def create_role(self, role_name, permissions='all'):
        """
        管理员创建新角色
        :param role_name: 角色名
        :param permissions: all所有权限，all_not没有权限，'日志中心,智能运维'权限
        :return:
        """
        self.log.info('步骤①：点击安全中心-角色与权限')
        menu_xpath = '//span[contains(@class,"arco-menu-title") ' \
                     'and text()="安全中心"]'
        sub_menu_xpath = '//span[contains(@class,"arco-menu-item-inner") ' \
                         'and text()="角色与权限"]'
        self.wait_click(menu_xpath)
        self.wait_click(sub_menu_xpath)

        self.log.info('步骤②：点击“添加角色”')
        btn_xpath = '//button[text()="添加角色"]'
        self.wait_click(btn_xpath)

        self.log.info('步骤③：选择一些菜单赋予权限')
        input_xpath = '//div[@class="arco-modal-body"]/descendant::' \
                      'input[@placeholder="请输入角色名称"]'
        self.input(input_xpath, role_name)

        label_xpath = '//*[text()="启用"]/ancestor::label[contains(' \
                      '@class,"arco-radio")]'
        cls_str = self.get_ele_attr(label_xpath, 'class')
        if 'arco-radio-checked' not in cls_str:
            self.wait_click(label_xpath)

        label_xpath = '//*[text()="全选/全不选"]/ancestor::label[contains(' \
                      '@class,"arco-checkbox")]'
        cls_str = self.get_ele_attr(label_xpath, 'class')
        if permissions == 'all':
            if 'arco-checkbox-checked' not in cls_str:
                self.wait_click(label_xpath)
        elif permissions == 'all_not':
            self.wait_click(label_xpath)
            cls_str = self.get_ele_attr(label_xpath, 'class')
            if 'arco-checkbox-checked' in cls_str:
                self.wait_click(label_xpath)
        else:
            self.wait_click(label_xpath)
            cls_str = self.get_ele_attr(label_xpath, 'class')
            if 'arco-checkbox-checked' in cls_str:
                self.wait_click(label_xpath)
            for p in permissions.split(','):
                xpath = f'//span[text()="{p}" and @class="arco-tree-node-' \
                    f'title-text"]/../preceding-sibling::label/span'
                self.wait_click(xpath)

        self.log.info('步骤④：点击确定')
        btn_xpath = '//div[@class="modal-footer"]/descendant::' \
                    'button[text()="确定"]'
        btn = self.find_eles(By.XPATH, btn_xpath)[1]
        btn.click()
        time.sleep(3)

        self.log.info('步骤⑤：关闭打开的tag')
        close_xpath = '//*[@class="tag-link" and text()="角色与权限"]/' \
                      'following-sibling::span'
        self.wait_click(close_xpath)

    def modify_role(self, role_name, permissions):
        """
        管理员修改角色权限
        :param role_name: 角色名
        :param permissions: all所有权限，all_not没有权限，'日志中心,智能运维'权限
        :return:
        """
        # 通过selenium定位元素再点击失败率很高，改用js
        js = "Array.from(document.querySelectorAll('span')).find(el => " \
             "el.textContent === '安全中心').click();"
        self.exec_js(js)
        time.sleep(1)
        js = "Array.from(document.querySelectorAll('span')).find(el => " \
             "el.textContent === '角色与权限').click();"
        self.exec_js(js)
        time.sleep(3)

        input_xpath = '//*[text()="查询"]/ancestor::div/' \
                      'preceding-sibling::div/descendant::' \
                      'input[@placeholder="请输入角色名称"]'
        self.wait_input(input_xpath, role_name)
        js = "Array.from(document.querySelectorAll('button')).find(el => " \
             "el.textContent === '查询').click();"
        self.exec_js(js)

        btn_xpath = f'//span[text()="{role_name}"]/ancestor::td/' \
            f'following-sibling::td/descendant::*[text()="修改"]'
        self.wait_click(btn_xpath)

        label_xpath = '//*[text()="全选/全不选"]/ancestor::label[contains(' \
                      '@class,"arco-checkbox")]'
        cls_str = self.get_ele_attr(label_xpath, 'class')
        if permissions == 'all':
            if 'arco-checkbox-checked' not in cls_str:
                self.wait_click(label_xpath)
        elif permissions == 'all_not':
            self.wait_click(label_xpath)
            cls_str = self.get_ele_attr(label_xpath, 'class')
            if 'arco-checkbox-checked' in cls_str:
                self.wait_click(label_xpath)
        else:
            self.wait_click(label_xpath)
            cls_str = self.get_ele_attr(label_xpath, 'class')
            if 'arco-checkbox-checked' in cls_str:
                self.wait_click(label_xpath)
            for p in permissions.split(','):
                xpath = f'//span[text()="{p}" and @class="arco-tree-node-' \
                    f'title-text"]/../preceding-sibling::label/span'
                self.wait_click(xpath)

        btn_xpath = '//div[@class="modal-footer"]/descendant::' \
                    'button[text()="确定"]'
        btn = self.find_eles(By.XPATH, btn_xpath)[1]
        btn.click()
        time.sleep(3)

        close_xpath = '//*[@class="tag-link" and text()="角色与权限"]/' \
                      'following-sibling::span'
        self.wait_click(close_xpath)

    def drop_role(self, role_name):
        # 通过selenium定位元素再点击失败率很高，改用js
        js = "Array.from(document.querySelectorAll('span')).find(el => " \
             "el.textContent === '安全中心').click();"
        self.exec_js(js)
        time.sleep(1)
        js = "Array.from(document.querySelectorAll('span')).find(el => " \
             "el.textContent === '角色与权限').click();"
        self.exec_js(js)
        time.sleep(3)

        input_xpath = '//*[text()="查询"]/ancestor::div/' \
                      'preceding-sibling::div/descendant::' \
                      'input[@placeholder="请输入角色名称"]'
        self.wait_input(input_xpath, role_name)
        js = "Array.from(document.querySelectorAll('button')).find(el => " \
             "el.textContent === '查询').click();"
        self.exec_js(js)

        btn_xpath = f'//span[text()="{role_name}"]/ancestor::td/' \
            f'following-sibling::td/descendant::*[text()="删除"]'
        self.wait_click(btn_xpath)

        sub_btn_xpath = '//*[text()="是否确认删除此角色"]/ancestor::div/' \
                        'descendant::button[text()="确定"]'
        self.wait_click(sub_btn_xpath)

        close_xpath = '//*[@class="tag-link" and text()="角色与权限"]/' \
                      'following-sibling::span'
        self.wait_click(close_xpath)